using Microsoft.AspNetCore.Mvc;
using SPI.AgentServer.Services.Metadata;
using Swashbuckle.AspNetCore.Annotations;

namespace SPI.AgentServer.Controllers;

/// <summary>
/// 数据库元数据管理控制器
/// </summary>
[ApiController]
[Route("api/schema")]
[Produces("application/json")]
[SwaggerTag("元数据管理 - 查看和管理数据库结构信息")]
public class SchemaController : ControllerBase
{
    private readonly ISchemaRegistry _schemaRegistry;
    private readonly ILogger<SchemaController> _logger;

    public SchemaController(ISchemaRegistry schemaRegistry, ILogger<SchemaController> logger)
    {
        _schemaRegistry = schemaRegistry;
        _logger = logger;
    }

    /// <summary>
    /// 获取可用数据库列表
    /// </summary>
    /// <returns>数据库名称列表</returns>
    [HttpGet("databases")]
    [ProducesResponseType(typeof(List<string>), StatusCodes.Status200OK)]
    [SwaggerOperation(
        Summary = "获取数据库列表",
        Description = "返回所有可用的数据库名称",
        OperationId = "ListDatabases",
        Tags = new[] { "元数据" }
    )]
    public async Task<IActionResult> ListDatabases()
    {
        try
        {
            var databases = await _schemaRegistry.ListDatabasesAsync();
            return Ok(databases);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error listing databases");
            return StatusCode(500, new { error = "Failed to list databases" });
        }
    }

    /// <summary>
    /// 获取数据库中的表列表
    /// </summary>
    /// <param name="database">数据库名称（可选）</param>
    /// <returns>表名列表</returns>
    [HttpGet("tables")]
    [ProducesResponseType(typeof(List<string>), StatusCodes.Status200OK)]
    [SwaggerOperation(
        Summary = "获取表列表",
        Description = "返回指定数据库中的所有表名",
        OperationId = "ListTables",
        Tags = new[] { "元数据" }
    )]
    public async Task<IActionResult> ListTables([FromQuery] string? database = null)
    {
        try
        {
            var tables = await _schemaRegistry.ListTablesAsync(database);
            return Ok(tables);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error listing tables");
            return StatusCode(500, new { error = "Failed to list tables" });
        }
    }

    /// <summary>
    /// 获取表的详细结构信息
    /// </summary>
    /// <param name="tableName">表名</param>
    /// <param name="database">数据库名称（可选）</param>
    /// <returns>表结构信息</returns>
    [HttpGet("table/{tableName}")]
    [ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [SwaggerOperation(
        Summary = "获取表结构",
        Description = "返回表的字段、类型、主键等详细信息",
        OperationId = "GetTableSchema",
        Tags = new[] { "元数据" }
    )]
    public async Task<IActionResult> GetTableSchema(string tableName, [FromQuery] string? database = null)
    {
        try
        {
            var schema = await _schemaRegistry.GetTableSchemaAsync(tableName, database);
            
            if (schema == null)
            {
                return NotFound(new { error = $"Table '{tableName}' not found" });
            }

            return Ok(schema);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting table schema");
            return StatusCode(500, new { error = "Failed to get table schema" });
        }
    }

    /// <summary>
    /// Get sample queries for a table
    /// </summary>
    [HttpGet("table/{tableName}/samples")]
    [ProducesResponseType(typeof(List<string>), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetSampleQueries(string tableName, [FromQuery] string? database = null)
    {
        try
        {
            var samples = await _schemaRegistry.GetSampleSqlAsync(tableName, database);
            return Ok(samples);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting sample queries");
            return StatusCode(500, new { error = "Failed to get sample queries" });
        }
    }

    /// <summary>
    /// Refresh schema cache
    /// </summary>
    [HttpPost("refresh")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    public async Task<IActionResult> RefreshSchema([FromQuery] string? database = null)
    {
        try
        {
            await _schemaRegistry.RefreshSchemaAsync(database);
            return NoContent();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error refreshing schema");
            return StatusCode(500, new { error = "Failed to refresh schema" });
        }
    }
}
